const pt = require('puppeteer');

module.exports = async function (options) {
    //linux环境下是要嵌套在try里面的
    try {
        //bs是browser浏览器的缩写， launch是发起启动的意思，pt启动一个浏览器
        const bs = await pt.launch({
            //headless: false, //headless 无头的意思，浏览器不带请求头去请求
            args: ['--no-sandbox', '--disable-setuid-sandbox'], //沙盒 沙箱
            handleSIGINT: false,
            ignoreDefaultArgs: ['--disable-extensions'],
            executablePath: '/root/.chromium-browser-snapshots/linux-722234/chrome-linux/chrome' //executablePath:可执行的路径
        }),
            pg = await bs.newPage(),//bs启动一个新的页面
            url = options.url;//爬取页面的url

        //pg.goto(url,):用上面启动的新的页面去打开这个url
        await pg.goto(url, {
            timeout: 0,//超时时间,0表示无穷大，线上环境一定要给无穷大，puppeteer爬取数据失败了它自己会去走子进程的
            waitUntil: 'networkidle2'//waitUtil:什么时候代表完成了呢，没有向网络发起连接了就表示爬取完成了，'networkidle2'这个状态也可以表示完成了，它表示不超过两个连接，它是官方推荐的，还有一个'networkidle0'，表示没有任何连接
        });

        //打开页面了就可以开始评估页面了，evaluate:分析，评估，
        //记住：options.callback函数内部其实就是爬取的页面的环境，比如页面中有jQuery的环境，我
        //们也可以直接拿到来用
        const result = await pg.evaluate(options.callback);

        // -----开始  这里是为了能解决爬取到第二页的数据做准备的，因为第二页的数据是通过点击按钮触发ajax请求后渲染的，普通的爬取是爬不到的
        //所以我们要进一步处理
        if (result && options.field === 'course') {
            await pg.waitForSelector('.page-btn.page-last');//等这个dom元素出现在这个页面
            await pg.click('.page-btn.page-last');//再去点击它
            await pg.waitFor(2000);//等待2秒钟，等数据出来，其实这时候就是第二页的数据了
            const res = await pg.evaluate(options.callback);//开始评估第二页的数据了
            await pg.waitFor(2000);//等待2秒钟 
            //上面爬取的第一页数据和这里爬取的第二页数据合并时，不要用concat方法直接合并，会出问题，合并不了
            //用for循环就能解决这个问题
            for (var i = 0; i < res.length; i++) {
                await result.push(res[i]);
            }
        }
        // -----结束


        await bs.close();//爬虫结束了之后，把浏览器关闭了

        process.send(result);//让进程发送消息，把result发过去，send发送出去之后，在进程里面是可以通过'message'这个事件监听到发送过来的数据的，结果交给回调函数的data

        setTimeout(() => {
            process.exit(0);//用完之后关闭进程
        }, 1000);
    } catch (error) {
        console.log(error);
    }
}